16 TRAITS = ["ethic","moral","tau","i","agility","strength","stamina","expertise"]
18 attr_accessor :traits_delta
20 def initialize(traits = Array.new(TRAITS.size, 0), traits_delta = Array.new(TRAITS.size, 0))
21 #puts "creating character with #{traits.join(',')}"
23 @traits_delta = traits_delta.to_a
26 def self.generate(something)
27 ch = doTehArithmancy(something).character
28 #puts "got a number: #{num} chr #{num.instance_variable_get(:@character)}"
34 return @traits_delta unless chr
35 tplus (tmult (tminus chr.traits, traits), factor), traits_delta
38 #that stuff is still kinda indirect.
40 @traits_delta = acc(chr, factor)
44 @traits = tplus @traits, @traits_delta
45 @traits_delta = tmult @traits_delta, 0.1
50 a.zip(b).map{|c| c[0]-c[1]}
54 a.zip(b).map{|c| c[0]+c[1]}
66 return Math::sqrt(@traits.inject(0){|a,e|a+e*e})
71 @traits = @traits.each_with_index.map do |v, i|
72 next v if ["tau", "i"].include? TRAITS[i]
84 @traits = params.zip(@traits).map{|a| a[0] || a[1]}
88 TRAITS.zip(@traits).map{|a| a[0]+": "+a[1].to_s }.join ","
91 def self.doTehArithmancy (something)
92 #puts "dta called: #{something.class}"
93 data = something.to_s.downcase.gsub(/[^a-z0-9]/,'')
94 return 0 unless data.length > 0
95 ary = data.chars.map do |c|
97 when '0'..'9' then c.ord-'0'.ord
98 when 'a'..'i' then c.ord-'a'.ord+1
99 when 'j'..'r' then c.ord-'j'.ord+1
100 when 's'..'z' then c.ord-'s'.ord+1
104 return doTehArithmancy ary.reduce :+
106 #puts "returning #{ary[0]} (a #{ary[0].class})"
107 #puts "chr: #{ary[0].instance_variable_get(:@character)}"
113 module Characterizable
114 def character= (*params)
115 @character = Character.new unless @character
116 @character.traits = params[0]
117 #puts "set character for #{self.to_s} to #{@character} according to #{params[0]}"
121 return @character if @character
122 #puts "generating character for #{self.to_s}"
123 ch = Character.generate self.to_s
124 @character = ch unless frozen?
130 include Characterizable
131 # ethic , moral , tau , i,agility,strength,stamina,expertise
132 0.character=Character::Ethic::NEUTRAL, Character::Moral::CHAOTIC, 2*Math::PI, 0, 0, 1, 1, 0
133 1.character=Character::Ethic::NEUTRAL, Character::Moral::LAWFUL , 2*Math::PI, 0, 0, 1, 1, 0
134 2.character=Character::Ethic::NEUTRAL, Character::Moral::NEUTRAL, 2*Math::PI, 0, 0, 1, 1, 0
135 3.character=Character::Ethic::GOOD , Character::Moral::LAWFUL , 2*Math::PI, 0, 0, 1, 1, 0
136 4.character=Character::Ethic::NEUTRAL, Character::Moral::LAWFUL , 2*Math::PI, 0, 0, 1, 1, 0
137 5.character=Character::Ethic::GOOD , Character::Moral::CHAOTIC, 2*Math::PI, 0, 0, 1, 1, 0
138 6.character=Character::Ethic::GOOD , Character::Moral::LAWFUL , 2*Math::PI, 0, 0, 1, 1, 0
139 7.character=Character::Ethic::GOOD , Character::Moral::NEUTRAL, 2*Math::PI, 0, 0, 1, 1, 0
140 8.character=Character::Ethic::NEUTRAL, Character::Moral::LAWFUL , 2*Math::PI, 0, 0, 1, 1, 0
141 9.character=Character::Ethic::NEUTRAL, Character::Moral::LAWFUL , 2*Math::PI, 0, 0, 1, 1, 0
145 include Characterizable
146 all_symbols.each do |sym|
153 name.to_sym.character
159 self.class.name.to_sym.character
162 def process_call(method, name, *args, &block)
163 rv = method.bind(self).call(*args, &block)
166 #puts "processing call: #{method} which is #{method.character || "uncharacteristic"} on #{self} which is a #{self.class} with #{character || "no character"} given #{args.size > 0?args:"no args"} and #{block || "no block"}"
171 args.each do |a| #FIXME constants ahead!
173 a.character.acc! name.character, 0.01
174 a.character.acc! character, 0.01
175 character.acc! a.character, 0.001
176 rv.character.acc! a.character, 0.001
177 name.character.acc! a.character, 0.001
179 rv.character.acc! name.character, 0.01
180 rv.character.acc! character, 0.002
181 character.acc! name.character, 0.001
188 def self.infect_method(name)
189 @@armed = false if @@armed
190 raw_method = self.instance_method(name.to_sym)
191 define_method name do |*args, &block|
192 self.process_call(raw_method, name, *args, &block)
194 @@armed = true if not @@armed.nil?
198 self.instance_methods.each do |m|
199 unless [:process_call, :bind, :call].include? m
200 #puts "\t-infecting #{m}"
206 def self.method_added(name)
207 infect_method(name) if @@armed
214 class_variable_set(:@@armed, nil)
221 class_variable_set(:@@armed, nil)
224 #infect global objects
225 ::Module.constants.each do |c|
226 unless [:Config].include? c
227 #puts "+infecting #{c}"
228 cs = ::Module.const_get(c)
229 cs.infect_all! if cs.is_a? ::Class
234 puts "Graf Zahl resurrected."